#include "pcrChartItem.h"

PCRChartItem::PCRChartItem(QWidget* parent){

    this->setParent(parent);
    _axisX = new QValueAxis(this);
    _axisY = new QValueAxis(this);
    this->legend()->hide();

    this->addAxis(_axisX, Qt::AlignBottom);
    this->addAxis(_axisY, Qt::AlignLeft);
    this->updateRange(0,1,0,1);

}


void PCRChartItem::updateCurve(){
    QString name;
    int changeTimes = 0;
    for(auto iter = _state.begin(); iter != _state.end(); iter ++){

        name = iter.key();
        if(_lastState[name] != _state[name]){
            _lastState[name] = _state[name];
            if(_state[name] == NORM || _state[name] == BOLD){
                _series[name]->setPen(getPen(name, _state[name]));
                _series[name]->show();
            }else{
                _series[name]->hide();
            }
            changeTimes ++;
        }
    }
    //qDebug("曲线变更次数: %d", changeTimes);
}

void PCRChartItem::updateRange(){
    _axisX->setRange(1, _xmax);
    _axisX->setTickCount(16);
    _axisX->setLabelFormat("%.0f");

    if(_ymax < 10){
        _axisY->setLabelFormat("%.1f");
        _ymax = std::ceil(_ymax);
        _ymin = std::floor(_ymin);
        _axisY->setTickCount(_ymax-_ymin+1);
        _axisY->setRange(_ymin, _ymax);
    }
    else{

        _axisY->setLabelFormat("%.0f");
        int ynum = std::floor(log10(_ymax));
        int ybase = pow(10, ynum-1);
        _ymax = std::ceil(_ymax / ybase) * ybase;

        _axisY->setRange(0, _ymax);
        _axisY->setTickCount(11);
    }
}

void PCRChartItem::updateRange(double xmin, double xmax, double ymin, double ymax){
    _axisX->setRange(xmin, xmax);
    _axisY->setRange(ymin, ymax);
}

void PCRChartItem::appendCurve(QString name, QVector<QPointF> pointList, QString type, ShowState state){
    // qDebug() << "添加曲线名：" << name;
    // 更新Range
    for(int i = 0; i < pointList.size(); i ++){
        // 更新坐标轴参数
        _xmax = std::max(pointList[i].x(), _xmax);
        _xmin = std::min(pointList[i].x(), _xmin);
        _ymax = std::max(pointList[i].y(), _ymax);
        _ymin = std::min(pointList[i].y(), _ymin);
    }
    if(_series.contains(name)){
        _series[name]->replace(pointList);
        return;
    }

    if(type == "spline"){
        QSplineSeries* ts = new QSplineSeries;
        ts->setName(name);
        ts->setPen(getPen(name, state));
        _series.insert(name, ts);
    }else if(type == "scatter"){
        QScatterSeries* ts = new QScatterSeries;
        ts->setName(name);
        ts->setPen(getPen(name, state));
        ts->setMarkerSize(5);
        ts->setBrush(QBrush(ts->pen().color()));
        _series.insert(name, ts);
    }else if(type == "line"){
        QLineSeries* ts = new QLineSeries;
        ts->setName(name);
        ts->setPen(getPen(name, state));
        _series.insert(name, ts);
    }
    _series[name]->replace(pointList);
    _lastState[name] = state;
    _state[name] = state;

    // 关联至chart
    this->addSeries(_series[name]);
    _series[name]->attachAxis(_axisX);
    _series[name]->attachAxis(_axisY);

}


QPen PCRChartItem::getPen(QString name, ShowState state){
    QPen pen;
    if(name.contains("FAM")){
        pen.setColor(QColor(66,  46,  205));
    }else if(name.contains("ROX")){
        pen.setColor(QColor(255, 135, 62));
    }else if(name.contains("CY5")){
        pen.setColor(QColor(255, 43,  55));
    }else if(name.contains("VIC")){
        pen.setColor(QColor(0  , 196, 115));
    }

    if(state == NORM){
        pen.setWidth(1);
    }if(state == BOLD || name.contains("THR")){
        pen.setWidth(3);
    }

    return pen;
}


void PCRChartItem::changeCurveState(QString name, ShowState state){
    if(!_series.contains(name)){
        return;
    }
    _state[name] = state;
}

void PCRChartItem::changeCurveState(const QStringList &names, ShowState state){
    foreach(QString name, names){
        if(!_series.contains(name)){
            continue;
        }
        _state[name] = state;
    }
}

void PCRChartItem::changeCurveState_reg(QString name, ShowState state){
    for(auto iter = _state.begin(); iter != _state.end(); iter ++){
        if(iter.key().contains(name)){
            iter.value() = state;
        }
    }
}
